
import { _decorator, Component, Node,Prefab,instantiate,Label } from 'cc';
import {PlayerController} from "./PlayerController";
const { ccclass, property } = _decorator;

/**
 * Predefined variables
 * Name = GameManager
 * DateTime = Sat Sep 18 2021 17:14:39 GMT+0800 (中国标准时间)
 * Author = pspring
 * FileBasename = GameManager.ts
 * FileBasenameNoExtension = GameManager
 * URL = db://assets/Scripts/GameManager.ts
 * ManualUrl = https://docs.cocos.com/creator/3.3/manual/zh/
 *
 */

/** 地图类型 */
enum BlockType {
    /** 陷阱 */
    GS_NONE,
    /** 路径 */
    GS_STONE
}

/** 游戏状态 */
enum GameState {
    GS_INIT,
    GS_PLAYING,
    GS_END
}
 
@ccclass('GameManager')
export class GameManager extends Component {
    // [1]
    // dummy = '';
    /** 赛道 */
    private _road: BlockType[] = [];
    /** 当前游戏状态 */
    private _curState: GameState = GameState.GS_INIT;
    /** 如果格子数量小于等于9，则增长9个格子 */
    private _lessRoad: number = 9;

    // [2]
    // @property
    // serializableDummy = 0;
    /** player 控制脚本 */
    @property({type: PlayerController})
    public playerCtrl: PlayerController | null = null;
    /** 开始ui */
    @property({type: Node})
    public startMenu: Node | null = null;
    /** 路径预制体 */
    @property({type: Prefab})
    public cubePrefab: Prefab | null = null;
    /** 步数显示ui */
    @property({type: Label})
    public step: Label | null = null;
    /** 赛道长度 */
    @property
    public roadLength: number = 24;

    start () {
        // [3]
        this.curState = GameState.GS_INIT;
        this.playerCtrl?.node.on("JumpEnd",this.onPlayerJumpEnd,this)
    }

    // update (deltaTime: number) {
    //     // [4]
    // }

    onPlayerJumpEnd(curMoveIndex: number) {
        if(curMoveIndex > this.roadLength || this._road[curMoveIndex] === BlockType.GS_NONE){
            this.curState = GameState.GS_INIT;
        }
        // 1.如果当前路径是陷阱，则停止
        if(this._road[curMoveIndex] === BlockType.GS_NONE){
            this.curState = GameState.GS_INIT;
        }
        // 2.如果格子数量小于等于9，则增长9个格子
        if(this.roadLength - curMoveIndex <= this._lessRoad){
            this.addGenerateRoad();
        }
        this.step.string = '' + (curMoveIndex > this.roadLength ? this.roadLength : curMoveIndex);
    }

    init(){
        // 打开ui
        this.startMenu.active = true;
        // 生成路径
        this.generateRoad();
        // 禁止接收用户操作人物移动指令
        this.playerCtrl.setInputActive(false);
        // 重置任务状态
        this.playerCtrl.reset();
    }

    onClickPlayButton(){
        this.curState = GameState.GS_PLAYING;
    }

    set curState(state: GameState) {
        if(state === GameState.GS_INIT){
            this.init();
        }else if(state === GameState.GS_PLAYING){
            // 关闭ui
            this.startMenu.active = false;
            this.step.string = '0';
            // 开始监听鼠标点击事件
            setTimeout(() => {
                if (this.playerCtrl) {
                    this.playerCtrl.setInputActive(true);
                }
            }, 0.1);
        }else{
            // GameState.End
        }
    }

    private generateRoad() {
        // 防止游戏重新开始时，赛道还是旧的赛道
        // 因此，需要移除旧赛道，清除旧赛道数据
        this.node.removeAllChildren();
        this._road = [];
        // 第一个格子不是陷阱
        this._road.push(BlockType.GS_STONE);
        // 确定好每一格的赛道类型
        for (let i = 1; i < this.roadLength; i++) {
            // 如果上一个赛道为坑，这个赛道一定不为坑
            if(this._road[i - 1] === BlockType.GS_NONE){
                this._road.push(BlockType.GS_STONE);
            }else{
                this._road.push(Math.floor(Math.random() * 2));
            }
        }
        // 根据赛道生成赛道类型
        for (let i = 0; i < this.roadLength; i++) {
            let blockType = this._road[i];
            if(blockType === BlockType.GS_STONE){
                let node = instantiate(this.cubePrefab);
                this.node.addChild(node);
                node.setPosition(i,-1.5,0);
            }
        }
    }

    /** 如果剩余赛道小于x，生成赛道 */
    private addGenerateRoad() {
        let length = this._road.length;
        let addRoad: BlockType[] = [];
        // 第一个格子不是陷阱
        addRoad.push(BlockType.GS_STONE);
        // 确定好每一格的赛道类型
        for (let i = 1; i < this._lessRoad; i++) {
            // 如果上一个赛道为坑，这个赛道一定不为坑
            if(addRoad[i - 1] === BlockType.GS_NONE){
                addRoad.push(BlockType.GS_STONE);
            }else{
                addRoad.push(Math.floor(Math.random() * 2));
            }
        }
        // 根据赛道生成赛道类型
        for (let i = 0; i < this._lessRoad; i++) {
            let blockType = addRoad[i];
            this._road.push(blockType);
            if(blockType === BlockType.GS_STONE){
                let node = instantiate(this.cubePrefab);
                this.node.addChild(node);
                node.setPosition(length + i,-1.5,0);
            }

        }
        this.roadLength += this._lessRoad;
    }

}

/**
 * [1] Class member could be defined like this.
 * [2] Use `property` decorator if your want the member to be serializable.
 * [3] Your initialization goes here.
 * [4] Your update function goes here.
 *
 * Learn more about scripting: https://docs.cocos.com/creator/3.3/manual/zh/scripting/
 * Learn more about CCClass: https://docs.cocos.com/creator/3.3/manual/zh/scripting/ccclass.html
 * Learn more about life-cycle callbacks: https://docs.cocos.com/creator/3.3/manual/zh/scripting/life-cycle-callbacks.html
 */
